package javacommon.web.util;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.lxh.smart.Request;


public class ServletRequestUtils {

	/**
	 * 将请求参数转换为int,如果没有name指定的参数,返回默认值
	 * @param request
	 * @param name
	 * @param defaultValue
	 * @return
	 */
    public static int getIntParameter(HttpServletRequest request, String name, int defaultValue) {
        if (request.getParameter(name)==null) {
            return defaultValue;
        }
        return Integer.parseInt(request.getParameter(name));
    }
    /**
     * 如果没有name指定的参数,返回默认值
     * @param request
     * @param name
     * @param defaultValue
     * @return
     */
    public static String getStringParameter(HttpServletRequest request, String name,
                                            String defaultValue) {
        if (request.getParameter(name)==null) {
            return defaultValue;
        }
        return request.getParameter(name);
    }
    
    public static boolean getBooleanParameter(ServletRequest request, String name, boolean defaultVal) {
		if (request.getParameter(name) == null) {
			return defaultVal;
		}
		try {
			return Boolean.parseBoolean(request.getParameter(name));
		} catch (Exception e) {
			return defaultVal;
		}
	}
    /**
     * 将request中的所有参数（parameter）转换为Map对象中的元素，返回Map对象<br>
     * 具体实现:<br>
     * 以前缀为标志,且去掉前缀作为键
     * @param request {@link ServletRequest}对象
     * @param prefix 参数名前缀
     * @return
     */
    public static Map<String, Object> getParametersStartingWith(ServletRequest request, String prefix) {
        //所有请求参数名
    	Enumeration<String> paramNames = request.getParameterNames();
    	//存放参数键值对的Map
        Map<String, Object> params = new TreeMap<String, Object>();
        if (prefix == null) {
            prefix = "";
        }
        while (paramNames != null && paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();//参数名
            //参数是否以前缀开头
            if ("".equals(prefix) || paramName.startsWith(prefix)) {
                //去除前缀
            	String unprefixed = paramName.substring(prefix.length());
                String[] values = request.getParameterValues(paramName);
                if (values == null || values.length == 0) {
                    // Do nothing, no values found at all.
                }
                else if (values.length > 1) {
                    params.put(unprefixed, values);//值可以是一个数组
                }
                else {
                    params.put(unprefixed, values[0]);//值可以是一个单值
                }
            }
        }
        return params;
    }
    
	/**
	 * 
	 * Parses a query string passed from the client to the server and builds a
	 * <code>HashTable</code> object with key-value pairs. The query string
	 * should be in the form of a string packaged by the GET or POST method,
	 * that is, it should have key-value pairs in the form <i>key=value</i>,
	 * with each pair separated from the next by a & character.
	 * 
	 * <p>
	 * A key can appear more than once in the query string with different
	 * values. However, the key appears only once in the hashtable, with its
	 * value being an array of strings containing the multiple values sent by
	 * the query string.
	 * 
	 * <p>
	 * When the keys and values are moved into the hashtable, any + characters
	 * are converted to spaces, and characters sent in hexadecimal notation
	 * (like <i>%xx</i>) are converted to ASCII characters.
	 * 
	 * @param queryString
	 *            a string containing the query to be parsed
	 * 
	 * @return a <code>HashTable</code> object built from the parsed key-value
	 *         pairs
	 * 
	 * @exception IllegalArgumentException
	 *                if the query string is invalid
	 * 
	 */

	static public HashMap<String, String[]> parseQueryString(String queryString) {
		String valArray[] = null;
		if (queryString == null) {
			throw new IllegalArgumentException("queryString must not null");
		}
		HashMap<String, String[]> map = new HashMap<String, String[]>();
		StringBuilder sb = new StringBuilder();
		StringTokenizer st = new StringTokenizer(queryString, "&");
		while (st.hasMoreTokens()) {
			String pair = (String) st.nextToken();
			if(pair.trim().length() == 0)
				continue;
			int pos = pair.indexOf('=');
			if (pos == -1) {
				throw new IllegalArgumentException("cannot parse queryString:"+queryString);
			}
			String key = parseName(pair.substring(0, pos), sb);
			String val = parseName(pair.substring(pos + 1, pair.length()), sb);
			if (map.containsKey(key)) {
				String oldVals[] = (String[]) map.get(key);
				valArray = new String[oldVals.length + 1];
				for (int i = 0; i < oldVals.length; i++)
					valArray[i] = oldVals[i];
				valArray[oldVals.length] = val;
			} else {
				valArray = new String[1];
				valArray[0] = val;
			}
			map.put(key, valArray);
		}
		return map;

	}
	/**
	 * 处理字符串中的特殊字符
	 * @param s
	 * @param sb
	 * @return
	 */
	static private String parseName(String s, StringBuilder sb) {
		sb.setLength(0);
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '+'://+转换为空格
				sb.append(' ');
				break;
			case '%':
				try {
					sb.append((char) Integer.parseInt(
							s.substring(i + 1, i + 3), 16));//转换%后的两个数字为16进制,进而转换为字符
					i += 2;//跳过后两个字符
				} catch (NumberFormatException e) {
					// need to be more specific about illegal arg
					throw new IllegalArgumentException();
				} catch (StringIndexOutOfBoundsException e) {
					String rest = s.substring(i);
					sb.append(rest);
					if (rest.length() == 2)
						i++;
				}
				break;
			default:
				sb.append(c);
				break;
			}
		}
		return sb.toString();
	}
	public static Map<String, Object> getParametersStartingWith(Request request,
			String prefix) {
		//所有请求参数名
    	Enumeration<String> paramNames = request.getParameterNames();
    	//存放参数键值对的Map
        Map<String, Object> params = new TreeMap<String, Object>();
        if (prefix == null) {
            prefix = "";
        }
        while (paramNames != null && paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();//参数名
            //参数是否以前缀开头
            if ("".equals(prefix) || paramName.startsWith(prefix)) {
                //去除前缀
            	String unprefixed = paramName.substring(prefix.length());
                String[] values = request.getParameterValues(paramName);
                if (values == null || values.length == 0) {
                    // Do nothing, no values found at all.
                }
                else if (values.length > 1) {
                    params.put(unprefixed, values);//值可以是一个数组
                }
                else {
                    params.put(unprefixed, values[0]);//值可以是一个单值
                }
            }
        }
        return params;
	}
}
